stubdom: implement pci coldplug
authorKeir Fraser <keir.fraser@citrix.com>
Wed, 21 Oct 2009 07:51:10 +0000 (08:51 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Wed, 21 Oct 2009 07:51:10 +0000 (08:51 +0100)
This patch fixes the circular dependency problem in the toolstack that
prevented pci coldplug from working with stubdoms: after creating the
stubdom we wait for it to be properly initialized before going
further. We release the domain lock while we wait.

Signed-off-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
tools/python/xen/xend/XendDomainInfo.py
tools/python/xen/xend/image.py
tools/python/xen/xend/server/pciif.py

index 70bd704a77004de9b71ea82b4d335199238dee72..aa8b5c2262d0a84e308fe7979048cec27b49b303 100644 (file)
@@ -687,7 +687,7 @@ class XendDomainInfo:
         # Test whether the devices can be assigned
 
         pci_name = pci_dict_to_bdf_str(new_dev)
-        _all_assigned_pci_devices =  get_all_assigned_pci_devices()
+        _all_assigned_pci_devices =  get_all_assigned_pci_devices(self.domid)
         if pci_name in _all_assigned_pci_devices:
             raise VmError("failed to assign device %s that has"
                           " already been assigned to other domain." % pci_name)
@@ -906,7 +906,7 @@ class XendDomainInfo:
                 self.pci_device_check_attachability(dev)
 
         # If pci platform does not exist, create and exit.
-        if existing_dev_info is None:
+        if pci_state == 'Initialising' :
             self.device_create(dev_sxp)
             return True
 
@@ -2253,11 +2253,12 @@ class XendDomainInfo:
             if devclass in XendDevices.valid_devices() and devclass != 'vscsi':
                 log.info("createDevice: %s : %s" % (devclass, scrub_password(config)))
                 dev_uuid = config.get('uuid')
-                devid = self._createDevice(devclass, config)
+                if devclass != 'pci' or not self.info.is_hvm() :
+                    devid = self._createDevice(devclass, config)
                 
-                # store devid in XendConfig for caching reasons
-                if dev_uuid in self.info['devices']:
-                    self.info['devices'][dev_uuid][1]['devid'] = devid
+                    # store devid in XendConfig for caching reasons
+                    if dev_uuid in self.info['devices']:
+                        self.info['devices'][dev_uuid][1]['devid'] = devid
 
             elif devclass == 'vscsi':
                 vscsi_config = config.get('devs', [])[0]
index d6127bfb932949068b1c5a3afa148b9736c03f08..bec74098382ca3e9fcbb6847076f6ca8b8dacfaa 100644 (file)
@@ -460,6 +460,27 @@ class ImageHandler:
         # we would very much prefer not to have a thread here and instead
         #  have a callback but sadly we don't have Twisted in xend
         self.sentinel_thread = thread.start_new_thread(self._sentinel_watch,())
+        if self.device_model.find('stubdom-dm') > -1 :
+            from xen.xend import XendDomain
+            domains = XendDomain.instance()
+            domains.domains_lock.release()
+
+            count = 0
+            while True:
+                orig_state = xstransact.Read("/local/domain/0/device-model/%i/state"
+                                    % self.vm.getDomid())
+                # This can occur right after start-up
+                if orig_state != None:
+                    break
+
+                log.debug('createDeviceModel %i: orig_state is None, retrying' % self.vm.getDomid())
+
+                time.sleep(0.1)
+                count += 1
+                if count < 100:
+                    continue
+
+            domains.domains_lock.acquire()
 
     def signalDeviceModel(self, cmd, ret, par = None):
         if self.device_model is None:
index 3d544110d6a088c719f7d277c08cddc6c97efc37..0e54ae14df89e7060081576e936cd6461b675e0d 100644 (file)
@@ -73,11 +73,16 @@ def get_assigned_pci_devices(domid):
         dev_str_list = dev_str_list + [dev_str]
     return dev_str_list
 
-def get_all_assigned_pci_devices():
+def get_all_assigned_pci_devices(domid = 0):
     dom_list = xstransact.List('/local/domain')
     pci_str_list = []
+    ti = 0
+    ts = xstransact.Read('/local/domain/' + str(domid) + '/target')
+    if ts is not None :
+        ti = int(ts)
     for d in dom_list:
-        if xstransact.Read('/local/domain/' + d + '/target') is None :
+        target = xstransact.Read('/local/domain/' + d + '/target')
+        if int(d) is not ti and target is None :
             pci_str_list = pci_str_list + get_assigned_pci_devices(int(d))
     return pci_str_list